/**
 * 键盘工具类
 */
class KeyboardUtils {
    private _keyDownFuncs:Array<any>;
    private _keyCodes:Array<any>;
    private _updateTime:number = 0;
    /**
     * 构造函数
     */
    public constructor() {
        this._keyCodes = [];
        this._keyDownFuncs = [];
        this._updateTime = 0;

        if (DeviceUtils.getIt().IsHtml5) {
            document.addEventListener("keyup",  (e) => {
                let keyCode = e["keyCode"];
                let codeIdx = this._keyCodes.indexOf(keyCode);
                if (codeIdx != -1) {
                    this._keyCodes.splice(codeIdx, 1);
                }

                this.update(0);
            });

            document.addEventListener("keydown", (e) => {   
                let keyCode = e["keyCode"];
                let codeIdx = this._keyCodes.indexOf(keyCode);
                if (codeIdx == -1) {
                    this._keyCodes.push(keyCode);
                } 
            });
        }
    }

    public update(dt:number):void {
        this._updateTime += dt;

        if (this._updateTime >= 100) {
            this._updateTime = 0;
            for (let i = 0; i < this._keyCodes.length; i++) {
                let keyCode = this._keyCodes[i];
                for (let j:number = 0 ; j < this._keyDownFuncs.length; j++) {
                    var func:Function = this._keyDownFuncs[j][0];
                    var target:any = this._keyDownFuncs[j][1];
                    if (func && target) {
                        func.apply(target, [keyCode]);
                    }
                }
            }
        }
    }   

    /**
     * 添加KeyDown事件
     * @param callback 回调函数
     * @param target 回调函数对应的对象
     */
    public addKeyDownCB(callback:Function, target:any):void {
        this._keyDownFuncs.push([callback, target]);
    }

    /**
     * 移除KeyDown事件
     * @param callback 回调函数
     * @param target 回调函数对应的对象
     */
    public removeKeyDownCB(callback:Function, target:any):void {
        for (var i = 0; i < this._keyDownFuncs.length; i++) {
            if (this._keyDownFuncs[i][0] == callback && this._keyDownFuncs[i][1] == target) {
                this._keyDownFuncs.splice(i, 1);
                i--;
            }
        }
    }

    private static _instance: KeyboardUtils;
    public static getIt(): KeyboardUtils {
        if(!this._instance)
            this._instance = new KeyboardUtils();

        return this._instance;
    }
}